home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / chibacity / gbbdisk.arj / CAROMAG / HEADER.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-07-19  |  12.8 KB  |  309 lines

  1. program investigate_header;  {Investigate a Windows 3.1 EXE header}
  2. uses crt;
  3.  
  4. type
  5.   OLD_HEADER_TYPE        =record
  6.     ID_Word              :word;    {Better be MZ}
  7.     Last_Page_Size       :word;    {Size of last page}
  8.     Page_Count           :word;    {512 byte blocks}
  9.     Rel_Table_Entries    :word;    {Entries in relocation table}
  10.     Header_Size          :word;    {16 byte paragraphs}
  11.     MINALLOC             :word;    {Min size program needs, 16 byte paragraphs}
  12.     MAXALLOC             :word;    {Max size program will take, 16 byte paragraphs}
  13.     Init_SS              :word;    {Initial stack (relocated)}
  14.     Init_SP              :word;
  15.     Checksum             :word;    {Normally not used}
  16.     Init_IP              :word;    {Entry point (relocated)}
  17.     Init_CS              :word;
  18.     Reloc_Table_Offset   :word;    {Location of relocation table, from start of file}
  19.                                    {If >=40H, then value at 3CH is offset to new style header}
  20.     Overlay_No           :word;    {Overlay number, 0 for programs}
  21.     Filler               :array[$1C..$3B] of byte;
  22.     New_Header_Offset    :word;
  23.     end;
  24.  
  25.   NEW_HEADER_TYPE        =record
  26.     Signature            :word;    {00 Better be NE}
  27.     Linker_Version       :byte;    {02 Self-explanatory}
  28.     Linker_Revision      :byte;    {03}
  29.     Entry_Table_Offset   :word;    {04}
  30.     Entry_Table_Length   :word;    {06}
  31.     Reserved1a           :word;    {08}
  32.     Reserved1b           :word;    {0A}
  33.     Flags                :word;    {0C}
  34.     Automatic_Data_Seg   :word;    {0E 0 if SINGLEDATA and MULTIPLEDATA not specified}
  35.     Local_Heap_Size      :word;    {10 Initial local heap size in bytes}
  36.     Stack_Size           :word;    {12 Initial stack size, in bytes}
  37.     Init_IP              :word;    {14 Initial entry point}
  38.     Init_CS              :word;    {16 Index to segment table!'}
  39.     Init_SP              :word;    {18 Initial stack}
  40.     Init_SS              :word;    {1A}
  41.     Segment_Table_Entries:word;    {1C Number of entries in segment table}
  42.     Mod_Ref_Table_Entries:word;    {1E Number of entries in module reference table}
  43.     Non_NameTable_Entries:word;    {20 Number of entries in non-resident name table}
  44.     Seg_Table_Offset     :word;    {22 Offset to segment table, from start of new header}
  45.     Resrc_Table_Offset   :word;    {24 Offset to resource table}
  46.     Res_Name_Table_Offset:word;    {26 Offset to resident name table}
  47.     Mod_Ref_Table_Offset :word;    {28 Offset to module reference table}
  48.     Imp_Name_Table_Offset:word;    {2A Offset to imported names table}
  49.     Nrs_Name_Table_Offset:longint; {2C Offset to non-resident name table, from BEGINNING of file in bytes}
  50.     Moveable_Entry_Pts   :word;    {30 Number of moveable entry points}
  51.     Seg_Alignment        :word;    {32 Log base 2 of segment sector size, defailt=9-->512 bytes}
  52.     Resource_Segments    :word;    {34 Specifies number of resource segments}
  53.     Op_system            :byte;    {36 Flags indicate what operating system this file is for 0=unknown, 1=OS/2, 2=Windows}
  54.     Flags2               :byte;    {37}
  55.     Fast_Load_Start      :word;    {38 Specifies start of fast load area}
  56.     Fast_Load_End        :word;    {3A End of fast load area}
  57.     Reserved2            :word;    {3C}
  58.     Win_Version          :word;    {3E Specifies windows version number}
  59.     end;
  60.  
  61.   SEG_TABLE_TYPE         =record
  62.     Offset               :word;
  63.     Size                 :word;
  64.     Attributes           :word;
  65.     Alloc                :word;
  66.     end;
  67.  
  68.   RES_INFO_TYPE          =record
  69.     ResType              :word;
  70.     Count                :word;
  71.     Reserved             :longint;
  72.     end;
  73.  
  74.   RES_NAME_INFO_TYPE     =record
  75.     Offset               :word;
  76.     Length               :word;
  77.     Flags                :word;
  78.     ID                   :word;
  79.     Handle               :word;
  80.     Usage                :word;
  81.     end;
  82.  
  83.   ENTRY_MOVEABLE_TYPE    =record
  84.     Flags                :byte;
  85.     INT_3F               :word;
  86.     Segment              :byte;
  87.     Offset               :word;
  88.     end;
  89.  
  90.   ENTRY_FIXED_TYPE       =record
  91.     Flags                :byte;
  92.     Offset               :word;
  93.     end;
  94.  
  95. var
  96.   f                :file;
  97.   fname            :string;
  98.   fo               :text;
  99.   foname           :string;
  100.   old_header       :OLD_HEADER_TYPE;
  101.   new_header       :NEW_HEADER_TYPE;
  102.   seg_table        :SEG_TABLE_TYPE;
  103.   i,j              :word;
  104.   module_name      :string;
  105.   resident_name    :string;
  106.   res_info         :RES_INFO_TYPE;
  107.   res_name_info    :RES_NAME_INFO_TYPE;
  108.   resource_name    :string;
  109.   seg_align        :longint;
  110.   res_align        :longint;
  111.   Entry_Moveable   :ENTRY_MOVEABLE_TYPE;
  112.   Entry_Fixed      :ENTRY_FIXED_TYPE;
  113.  
  114. function hex(w:word):string;
  115. const h:array[0..15] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
  116. begin
  117.   hex:=h[w div 4096] + h[(w div 256) and 15] + h[(w div 16) and 15] + h[w and 15];
  118. end;
  119.  
  120. function imported_name(j:word):string;
  121. var
  122.   s                :string;
  123.   n,i              :word;
  124. begin
  125.   n:=1;
  126.   for i:=1 to j do
  127.     begin
  128.       seek(f,old_header.New_Header_Offset+new_header.Imp_Name_Table_Offset+n);
  129.       blockread(f,s,255);
  130.       if ord(s[0])>0 then n:=n+ord(s[0])+1;
  131.     end;
  132.   imported_name:=s;
  133. end;
  134.  
  135. begin
  136.   fname:=ParamStr(1);
  137.   if ParamCount<>2 then AssignCRT(fo) else
  138.     begin
  139.       foname:=ParamStr(2);
  140.       assign(fo,foname);
  141.     end;
  142.   rewrite(fo);
  143.   assign(f,fname);
  144.   reset(f,1);                   {open with 1 byte block}
  145.   blockread(f,old_header,sizeof(old_header));
  146.   if ParamCount<>2 then ClrScr;
  147.   if old_header.ID_Word=ord('M')+256*ord('Z') then with old_header do
  148.     begin
  149.       writeln(fo,'Page count =                    ',Page_Count);
  150.       writeln(fo,'Last page size =                ',Last_Page_Size);
  151.       writeln(fo,'Relocation table entries =      ',Rel_Table_Entries);
  152.       writeln(fo,'Header size (bytes) =           ',Header_Size*16);
  153.       writeln(fo,'MINALLOC (16 byte paragraphs) = ',MINALLOC);
  154.       writeln(fo,'MAXALLOC (16 byte paragraphs) = ',MAXALLOC);
  155.       writeln(fo,'Initial SS:SP =                 ',hex(Init_SS),':',hex(Init_SP),'H');
  156.       writeln(fo,'Initial CS:IP =                 ',hex(Init_CS),':',hex(Init_SP),'H');
  157.       writeln(fo,'Checksum =                      ',hex(Checksum),'H');
  158.       writeln(fo,'Relocation Table Offset =       ',Reloc_Table_Offset);
  159.       writeln(fo,'Overlay number =                ',Overlay_No);
  160.     end
  161.   else
  162.     begin
  163.       writeln(fo,'This is not an EXE file!!');
  164.       halt;
  165.     end;
  166.   if old_header.Reloc_Table_Offset>=$40 then
  167.     begin
  168.       writeln(fo,'New Header Offset  =            ',old_header.New_Header_Offset);
  169.       writeln(fo);
  170.       writeln(fo,'This is a Windows or OS/2 executable file!');
  171.       writeln(fo,'Press any key to view new-style header.');
  172.       if ParamCount<>2 then if ReadKey=' ' then;
  173.       seek(f,old_header.New_Header_Offset);
  174.       blockread(f,new_header,sizeof(new_header));
  175.       if ParamCount<>2 then clrscr;
  176.       with new_header do    {Display header info}
  177.         begin
  178.           writeln(fo,'Header type =                    ',char(Signature and 255),char(Signature shr 8));
  179.           writeln(fo,'Initial CS:IP =                  #',Init_CS,':',hex(Init_IP),'H');
  180.           writeln(fo,'Initial SS:SP =                  #',Init_SS,':',hex(Init_SP),'H Size = ',Stack_Size);
  181.           writeln(fo,'Segment table entries =          ',Segment_Table_Entries);
  182.           writeln(fo,'Module reference table entries = ',Mod_Ref_Table_Entries);
  183.           writeln(fo,'Moveable entry points =          ',Moveable_Entry_Pts);
  184.           writeln(fo,'Resource segments =              ',Resource_Segments);
  185.           writeln(fo,'Automatic data segment =         ',Automatic_Data_Seg);
  186.           writeln(fo,'Fast load offset =               ',Fast_Load_Start);
  187.           case op_system of
  188.             1 : writeln(fo,'This is an OS/2 program.');
  189.             2 : writeln(fo,'This is a Windows program.');
  190.             end;
  191.         end;
  192.       writeln(fo);
  193.       write(fo,'Modules referenced: ');
  194.       for i:=1 to new_header.Mod_Ref_Table_Entries do
  195.         begin
  196.           seek(f,old_header.New_Header_Offset+new_header.Mod_Ref_Table_Offset+2*(i-1));
  197.           blockread(f,j,2);
  198.           seek(f,old_header.New_Header_Offset+new_header.Imp_Name_Table_Offset+j);
  199.           blockread(f,module_name,256);
  200.           write(fo,module_name,' ');
  201.         end;
  202.       writeln(fo);
  203.       writeln(fo,'Press any key to continue.');
  204.       if ParamCount<>2 then if ReadKey=' ' then ;
  205.       writeln(fo);
  206.       write(fo,'Resident names: ');
  207.       j:=0;
  208.       repeat
  209.         seek(f,old_header.New_Header_Offset+new_header.Res_Name_Table_Offset+j);
  210.         blockread(f,resident_name,256);
  211.         j:=j+ord(resident_name[0])+2;
  212.         write(fo,resident_name,' ');
  213.       until resident_name[0]=#0;
  214.       writeln(fo);
  215.       writeln(fo,'Non-resident names: ');
  216.       j:=0;
  217.       repeat
  218.         seek(f,new_header.NRS_Name_Table_Offset+j);
  219.         blockread(f,resident_name,256);
  220.         j:=j+ord(resident_name[0])+3;
  221.         writeln(fo,'  ',resident_name);
  222.       until resident_name[0]=#0;
  223.       writeln(fo);
  224.       seg_align:=1;
  225.       if new_header.Seg_Alignment<>0 then for i:=1 to new_header.Seg_Alignment do seg_align:=2*seg_align
  226.       else seg_align:=512;
  227.       writeln(fo,'Segments: (Alignment=',seg_align,'(',new_header.Seg_Alignment,'))');
  228.       writeln(fo,'Offset   Length   Alloc Size   Attributes');
  229.       for i:=1 to new_header.Segment_Table_Entries do
  230.         begin
  231.           seek(f,old_header.New_Header_Offset+new_header.Seg_Table_Offset+8*(i-1));
  232.           blockread(f,seg_table,sizeof(seg_table));
  233.           write(fo,seg_table.offset:5,seg_table.size:9,seg_table.alloc:13,'    ');
  234.           if seg_table.attributes and 1 = 1 then write(fo,'DATA ') else write(fo,'CODE ');
  235.           if seg_table.attributes and 2 = 2 then write(fo,'Allocated ');
  236.           if seg_table.attributes and 4 = 4 then write(fo,'Loaded ');
  237.           if seg_table.attributes and 16 = 16 then write(fo,'Moveable ') else write(fo,'Fixed ');
  238.           if seg_table.attributes and 32 = 32 then write(fo,'Shareable ');
  239.           if seg_table.attributes and 64 = 64 then write(fo,'Preload ');
  240.           if seg_table.attributes and 128 = 128 then write(fo,'Exec_Only/Read_Only ');
  241.           if seg_table.attributes and 256 = 256 then write(fo,'Contains_Rel_Data ');
  242.           if seg_table.attributes and 4096 = 4096 then write(fo,'Discardable ');
  243.           writeln(fo);
  244.         end;
  245.       writeln(fo);
  246. if new_header.Resource_segments<>0 then
  247.   begin
  248.       seek(f,old_header.New_Header_Offset+new_header.Resrc_Table_Offset);
  249.       blockread(f,j,2);
  250.       res_align:=1;
  251.       for i:=1 to j do res_align:=2*res_align;
  252.       writeln(fo,'Resources: (Alignment=',res_align,')');
  253.       writeln(fo,'Offset    Length  ID');
  254.       repeat
  255.         blockread(f,res_info,sizeof(res_info));
  256.         if Res_Info.ResType<>0 then for i:=1 to res_info.count do
  257.           begin
  258.             blockread(f,res_name_info,sizeof(res_name_info));
  259.             write(fo,res_name_info.Offset:5,'(',res_align*res_name_info.Offset,')',res_name_info.length:10,'   ');
  260.             if res_name_info.ID>=$8000 then writeln(fo,res_name_info.ID-$8000)
  261.             else
  262.               begin
  263.                 j:=filepos(f);
  264.                 seek(f,old_header.New_Header_Offset+new_header.Resrc_Table_Offset+res_name_info.ID);
  265.                 blockread(f,resource_name,256);
  266.                 writeln(fo,resource_name);
  267.                 seek(f,j);
  268.               end;
  269.           end;
  270.       until Res_Info.ResType=0;
  271.   end
  272. else writeln(fo,'There are no resources.');
  273.       writeln(fo);
  274.       writeln(fo,'Entry table:');
  275.       seek(f,old_header.New_Header_Offset+new_header.Entry_Table_Offset);
  276.       repeat
  277.         blockread(f,j,2);
  278.         if j shr 8 = $FF then
  279.           begin
  280.             writeln(fo,'Moveable:');
  281.             for i:=1 to j and $FF do
  282.               begin
  283.                 blockread(f,Entry_Moveable,sizeof(Entry_Moveable));
  284.                 writeln(fo,Entry_Moveable.Segment,':',hex(Entry_Moveable.Offset));
  285.               end;
  286.           end;
  287.         if j shr 8 = $FE then
  288.           begin
  289.             writeln(fo,'Constant:');
  290.           end;
  291.         if not (j shr 8 in [0,$FE,$FF]) then
  292.           begin
  293.             writeln(fo,'Fixed: (',j and $FF,')');
  294.             for i:=1 to j and $FF do
  295.               begin
  296.                 blockread(f,Entry_Fixed,sizeof(Entry_Fixed));
  297.                 writeln(fo,j shr 8,':',hex(Entry_Fixed.Offset));
  298.               end;
  299.           end;
  300.       until (j and $FF) = 0;
  301.     end
  302.   else writeln(fo,'This is a standard DOS EXE file.');
  303.   writeln(fo);
  304.   writeln(fo,'Press any key to continue.');
  305.   if ParamCount<>2 then if ReadKey=' ' then ;
  306.   close(fo);
  307.   close(f);
  308. end.
  309.